package extend.db.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

/**
 * db 帮助类
 *<B>说明：</B>
 *<pre>
 *  略
 *</pre>
 *<B>示例：</B>
 *<pre>
 *  略
 *</pre>
 *<B>日志：</B>
 *<pre>
 *  略
 *</pre>
 *<B>注意事项：</B>
 *<pre>
 *  略
 *</pre>
 */
public class DbUtil
{
    public static final String JAVA_TYPE_STRING = "java.lang.String";

    public static final String CLASS_DESC = "desc";

    /**
     * 父类第一位
     */
    public static final String CLASS_ASC = "asc";

    /**
     * 执行对象方法
     *<B>说明：</B>
     *<pre>
     *  利用反射机制执行对象的方法
     *</pre>
     * @param methodName 方法名
     * @param owner 对象名
     * @param args 参数
     * @return Object
     */
    public static Object invoke(String methodName,Object owner,Object... args) throws Exception
    {
        Class ownerClass = owner.getClass();
        try {
            Class[] argsClass = new Class[args.length];
            for (int i = 0, j = args.length; i < j; i++) {
                argsClass[i] = args[i].getClass();
            }

            Method method = ownerClass.getMethod(methodName,argsClass);
            return method.invoke(owner, args);
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("class " + ownerClass.toString() + " method " + methodName + " not find" + e.toString());
        }
    }

    /**
     * 执行对象方法
     *<B>说明：</B>
     *<pre>
     *  利用反射机制执行对象的方法
     *</pre>
     * @param method
     * @param args
     * @return Object
     */
    public static Object invoke(Object[] method,Object[] args) throws Exception
    {
        String methodName =  (String)method[0];
        Object owner =  method[1];
        Class ownerClass = owner.getClass();

        try {

            Class[] argsClass = new Class[args.length];
            for (int i = 0, j = args.length; i < j; i++) {
                argsClass[i] = args[i].getClass();
            }

            Method ownerMethod = ownerClass.getMethod(methodName,argsClass);
            return ownerMethod.invoke(owner, args);
        } catch (Exception e) {
            throw new Exception("class " + ownerClass.toString() + " method " + methodName +" not find");
        }
    }

    /**
     * 创建对象
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param className 类名
     * @param args
     * @return Object
     */
    public static Object make(String className,Object[] args) throws Exception
    {
        try {
            Class[] argsClass = new Class[args.length];
            for (int i = 0, j = args.length; i < j; i++) {
                if (args[i] instanceof Map) {
                    argsClass[i] = Map.class;
                } else {
                    argsClass[i] = args[i].getClass();
                }
            }

            // 加载类库
            Class cls = Class.forName(className);

            // 获取构造方法
            Constructor constructor = cls.getDeclaredConstructor(argsClass);
            return constructor.newInstance(args);
        } catch (Exception e) {
            throw new Exception("class className make fail");
        }
    }

    /**
     * 设置对象属性
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param attrs
     * @param object
     */
    public static void attr(Map<String,Object> attrs,Object object)
    {
       attr(attrs,object,CLASS_ASC);
    }

    /**
     * 设置对象属性
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param attrs 属性数据
     * @param object　对象
     * @param classSort class 遍历规则
     */
    public static void attr(Map<String,Object> attrs,Object object,String classSort)
    {
        Class targetClazz = object.getClass();
        for (Map.Entry<String, Object> attr : attrs.entrySet()) {
            try {
                Field field = getField(targetClazz,attr.getKey(),classSort);

                if (field != null) {
                    field.setAccessible(true);
                    field.set(object,attr.getValue());
                }

            } catch (Exception e) {
                // 不做任何事情
            }
        }
    }

    /**
     * 获取对象属性
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param className class 对象
     * @param fieldName 属性名
     * @param classSort class 遍历规则
     * @return 属性对象
     */
    public static Field getField(Class className,String fieldName,String classSort)
    {
        // 读取所有父类及本来
        List<Class> superClasss = getAllClass(className);
        if (classSort.equals(CLASS_ASC)) {
            Collections.reverse(superClasss);
        }

        Field field = null ;
        for (int i = 0;i < superClasss.size();i++)  {
            field = getDeclaredField(superClasss.get(i),fieldName);
            if (field != null) {
                // 找到属性,保持至至缓存
                break;
            }
        }

        return field;
    }

    /**
     * 获取类属性对象
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param className class 对象
     * @param attrName 属性名
     */
    public static Field getDeclaredField(Class className, String attrName)
    {

        Field field = null ;

        try {
            field = className.getDeclaredField(attrName) ;
            return field ;
        } catch (Exception e) {
            // 找不到属性
            return null;
        }
    }

    /**
     * 获取所有父类包括自己
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param targetClass
     */
    public static List<Class> getAllClass(Class targetClass)
    {
        List<Class> superClasss = new ArrayList<>();
        superClasss.add(targetClass);

        while (true) {//当父类为null的时候说明到达了最上层的父类(Object类).
            targetClass = targetClass.getSuperclass(); //得到父类,然后赋给自己
            if (targetClass != null && !targetClass.getSimpleName().equals("Object")) {
                superClasss.add(targetClass);
            } else {
                break;
            }
        }

        return superClasss;
    }

    public static String upperCase(String str)
    {
        char[] ch = str.toCharArray();
        if (ch[0] >= 'a' && ch[0] <= 'z') {
            ch[0] = (char) (ch[0] - 32);
        }
        return new String(ch);
    }

    public static StringBuilder join(Object[] array, String separator) {
        return array == null?null:join(array, separator, 0, array.length);
    }

    /**
     * 数组转字符串
     *<B>说明：</B>
     *<pre>
     *  以分隔符连接数组
     *</pre>
     * @param array 数组
     * @param separator 分隔符
     * @param startIndex 起始索引
     * @param endIndex 结束索引
     */
    public static StringBuilder join(Object[] array, String separator, int startIndex, int endIndex)
    {
        if(array == null) {
            return new StringBuilder();
        } else {
            if(separator == null) {
                separator = "";
            }

            int noOfItems = endIndex - startIndex;
            if(noOfItems <= 0) {
                return new StringBuilder();
            } else {
                StringBuilder buf = new StringBuilder(noOfItems * 16);

                for(int i = startIndex; i < endIndex; ++i) {
                    if(i > startIndex) {
                        buf.append(separator);
                    }

                    if(array[i] != null) {
                        buf.append(array[i]);
                    }
                }

                return buf;
            }
        }
    }

}
